﻿#region File Header
/***********************************************************************
 * Copyright © 2013 Beals Software
 * All Rights Reserved
************************************************************************
Author: Donald Beals
Date: February 4th, 2013
Description: TODO: Write a description of this file here.
****************************** Change Log ******************************
02.04.13 - Created initial file. (dbeals)
***********************************************************************/
#endregion

#region Using Statements
using System;
using GameJolt.Async;
using GameJolt.Requests;
#endregion

namespace GameJolt
{
	/// <summary>
	/// 
	/// </summary>
	public sealed class Session
	{
		#region Variables
		private SessionStatus status = SessionStatus.Unknown;
		#endregion

		#region Properties
		public string Username
		{
			get;
			set;
		}

		public string UserToken
		{
			get;
			set;
		}

		public SessionStatus Status
		{
			get
			{
				return status;
			}
			set
			{
				status = value;
			}
		}

		public bool IsValid
		{
			get;
			private set;
		}
		#endregion

		#region Constructors
		public Session(string username, string userToken)
		{
			this.Username = username;
			this.UserToken = userToken;
		}
		#endregion

		#region Methods
		public IAsyncResult BeginOpen(string gameID, string privateKey, AsyncCallback callback = null, object asyncState = null)
		{
			var request = SessionRequestFactory.CreateOpenRequest(gameID, privateKey, this.Username, this.UserToken);
			return request.Begin(callback, asyncState);
		}

		public string EndOpen(IAsyncResult result)
		{
			var joltResult = (AsyncResult<string>)result;
			var request = (StringRequest)joltResult.CoreData;
			var data = request.End(result);
			this.IsValid = RequestHelper.WasSuccessful(data);
			return data;
		}

		public string Open(string gameID, string privateKey)
		{
			var request = SessionRequestFactory.CreateOpenRequest(gameID, privateKey, this.Username, this.UserToken);
			var data = request.Process(null);
			this.IsValid = RequestHelper.WasSuccessful(data);
			return data;
		}

		public IAsyncResult Open(string gameID, string privateKey, Action<string> callback)
		{
			return BeginOpen(gameID, privateKey, (result) =>
			{
				var data = EndOpen(result);
				this.IsValid = RequestHelper.WasSuccessful(data);
				callback(data);
			});
		}

		public IAsyncResult BeginPing(string gameID, string privateKey, AsyncCallback callback = null, object asyncState = null)
		{
			var request = SessionRequestFactory.CreatePingRequest(gameID, privateKey, this.Username, this.UserToken, Status);
			return request.Begin(callback, asyncState);
		}

		public string EndPing(IAsyncResult result)
		{
			var joltResult = (AsyncResult<string>)result;
			var request = (StringRequest)joltResult.CoreData;
			var data = request.End(result);
			return data;
		}

		public string Ping(string gameID, string privateKey)
		{
			var request = SessionRequestFactory.CreatePingRequest(gameID, privateKey, this.Username, this.UserToken, Status);
			return request.Process(null);
		}

		public IAsyncResult Ping(string gameID, string privateKey, Action<string> callback)
		{
			return BeginPing(gameID, privateKey, (result) => callback(EndPing(result)));
		}

		public IAsyncResult BeginClose(string gameID, string privateKey, AsyncCallback callback = null, object asyncState = null)
		{
			var request = SessionRequestFactory.CreateCloseRequest(gameID, privateKey, this.Username, this.UserToken);
			return request.Begin(callback, asyncState);
		}

		public string EndClose(IAsyncResult result)
		{
			var joltResult = (AsyncResult<string>)result;
			var request = (StringRequest)joltResult.CoreData;
			var data = request.End(result);
			this.Status = SessionStatus.Closed;
			this.IsValid = false;
			return data;
		}

		public string Close(string gameID, string privateKey)
		{
			var request = SessionRequestFactory.CreateCloseRequest(gameID, privateKey, this.Username, this.UserToken);
			return request.Process(null);
		}

		public IAsyncResult Close(string gameID, string privateKey, Action<string> callback)
		{
			return BeginClose(gameID, privateKey, (result) => callback(EndClose(null)));
		}
		#endregion
	}
}
